![]() |
Программирование для Internet |
||
|
Сегодня речь пойдет о работе с окнами и фреймами. Для начала следует четко разделить эти понятия.
Окном мы будем называть независимое окно браузера, которое можно самостоятельно закрыть или наоборот, оставить открытым после закрытия первого, основного окна. Можно сказать, что все окна независимы и являются клонами одного и того же объекта.
Если Вы просматриваете этот текст с помощью браузера, Вы уже видите перед собою окно. Пример подобного окна - на рисунке справа.
Фрейм - это часть окна. Однако, в отличие от таблицы или, скажем, изображения,
фрейм имеет многие свойства окна. Например, фрейм имеет собственное свойство
location и, стало быть, во фрейм можно загрузить независимый документ.
Обычно фреймы и используются для одновременного просмотра нескольких документов.
На рисунке слева, во фреймы специально не загружено никаких "разумных" документов.
Фреймы там просто подписаны, чтобы Вы могли четко уяснить себе что это такое.
Конечно же, в любой из трех фреймов можно загруэить "разумный" документ.
Мы здесь не будем проводить разницы между обычными и плавающими фреймами (FRAME и IFRAME) т.к. разница между ними существует только для дизайнера. Методы же работы, с обоими видами фреймов, идентичны.
Как уже было сказано, фреймы обладают многими свойствами окна. Однако, их нельзя независимо создать (вне окна, они теряют смысл) или, скажем, удалить. Поэтому для фреймов не возникает проблемы существования. Если фрейм создан в некотором окне, то он будет существовать, пока существует окно.
Главное же сходство фреймов и окон заключается в том, что и туда и туда загружаются самостоятельные документы. Отсюда и общая проблема при работе и с фреймами и с окнами - проверка того, закончилась ли загрузка документа в окно/фрейм или еще продолжается.
Однако, прежде чем переходить к рассмотрению окон и фреймов, познакомимся с очень
полезным видом записи URL.
Иногда, бывает полезно воспользоваться псевдопротоколом javascript:. "Псевдо" потому, что, на самом деле, это не протокол. URL такого вида не вызывают никакой загрузки документа из сети. Просто, вместо документа, будет использован результат выражения, записанного после javascript:. Если же результат вычисления этого выражения равен null, то никаких действий не производится.
Таким образом, мы можем воспользоваться таким протоколом тогда, когда мы не хотим загружать документ из сети, а хотим сформировать его прямо в своей программе.
URL такого вида можно использовать везде, где можно использовать обычный URL, т.е. в гиперссылках, при открытии окон, в параметре SRC тэга FRAME и т.д. Если нам не нужно загружать никакого документа, а нам просто нужна ссылка, при нажатии на которую, ничего не происходит (допустим, мы просто хотим обработать событие click особым образом), мы можем записать javascript:void(0) (результат равен null). Если нам нужно создать пустой документ, мы можем записать javascript:''. Если же нужен конкретный документ, после javascript: можно писать константу, переменную, вызов функции, ... все что угодно, лишь бы то, что мы написали имело строковое значение. Вот это самое значение - эта самая строка - и будет содержимым документа, который откроется при нажатии на ссылку, загрузится во фрейм и т.д.
Например:
<A HREF="javascript:void(0)">Неработающая ссылка</A><A HREF="javascript:''">Пустой документ</A>
<A HREF="javascript:'Hello, world!'">Документ Hello, world!</A>
Начнем с того, что, когда Вы запускаете браузер, Вы, тем самым, уже создаете окно браузера (на самом деле, это делает операционная система, но мы не будем вдаваться в эти тонкости, возможно, Вам приятно ощущать свое могущество :-)
Иногда же возникает необходимость создать еще одно окно (или несколько), чтобы загрузить туда другой документ или даже поместить туда документ, сгенерированный Вашей JavaSript программой "на лету".
Для этого используется метод open объекта window.
open(url, имя окна, параметры);
первый аргумент - документ, который следует загрузить во вновь создаваемое окно. Второй - имя окна (значение свойства name нового объекта window). Третий - параметры создания окна.
Параметры создания окна:
Например:
open("http://joker.botik.ru/ip/images/window.gif","ps", "width=276 height=210 scrollbars=no resizable=no "+ "menubar=no location=no status=no toolbar=no");
Как всегда, мы опускаем указание на объект window, т.к. он используется по умолчанию.
Надеюсь, окно создалось благополучно.
Что же мы может теперь сделать с этим окном? На самом деле, более важным является вопрос, а что мы хотим с ним сделать? Если мы хотели просто загрузить документ, что бы пользователь его посмотрел (например, рекламу фирмы "Рога и копыта"), то цель уже достигнута и больше нам ничего делать и не нужно.
Другое дело, если мы хотим, из своей программы, иметь доступ к объектам, расположенным в новом окне или, например, иметь возможность закрыть его, когда оно нам более не будет нужно.
В этом случае нам необходимо воспользоваться значением, которое возвращает метод open. С помощью этого значения, мы и будем впредь работать с вновь созданным окном.
Например:
var newWindow = open("","myWin","location=no"); newWindow.document.writeln("<H1>Hello world!</H1>Содержимое этого "+ "окна сгенерировано <B>JavaScript</B> программой.<P>");
Обратите внимание, что на этот раз, мы явно указали к какому окну относится document.writeln(). Если раньше, мы всегда писали просто document.writeln() (или, что тоже самое - window.document.writeln()) и это относилось к нашему текущему окну, то теперь мы явно указали, к документу какого именно окна мы обращаемся!
В этом и состоит вся "хитрость" работы с окнами. Окно - это объект. Значит, если мы укажем с каким объектом мы намерены иметь дело, мы можем использовать все свойства и методы этого объекта! Таким образом, все, что мы усеем делать со своим родным окном, можно делать и посторонним, нужно только всегда указывать с каким именно окном мы работаем.
Давайте, например, закроем недавно созданное окно. Для этого запишем:
newWindow.close();
Чтобы эффективно работать с окнами, нужно знать еще несколько вещей:
Рассмотрим серию примеров. В приведенной ниже таблице, все кнопки, в ответ на событие click, вызывают функции, записанные над ними. В правом столбце приведены комментарии. Разбирайте пожалуйста тексты функций и выполняйте примеры последовательно. Не слишком много смысла записывать что-то в еще не соданное окно.
Остался, правда, невыясненным один вопрос: как из JavaScript программы одного окна обращаться к переменным и функциям другого?
Ответ вряд-ли покажется неожиданным. Дело в том, что функции и глобальные переменные, определенные нами в окне, есть попросту методы и свойства, добавленные нами к объекту window. А это значит, что обращаться к ним можно точно также, как к формам и другим элементам - указывая идентификатор окна перед именем функции или переменной. Например:
var newWin = open("http://www.botik.ru/","botik",""); newWin.initAll(); // обращение к функции initAll() определенной // в документе http://www.botik.ru/
Другой пример. Допустим, мы создаем сайт из нескольких страниц, которые порождают друг друга в новых окнах. Прежде чем порождающая страница начнет работать с документом в порожденном окне, хотелось бы убедиться в том, что документ в порожденном окне уже загрузился из сети. В этом случае, уместно определить в главном окне специальную переменную, которая изначально равна false. А документ порожденного окна должет присвоить ей true как только загрузится. Это могло бы выглядеть так:
В документе главного окна var childLoaded = false; var newWin = open("http://www.botik.ru/","botik",""); В документе порождаемого окна <BODY ONLOAD="opener.childLoaded=true">
На самом деле, мы можем использовать любые элементы одного окна из наших программ, определенных в другом окне. Например, функции, определенные в одном документе, могут обрабатывать события происшедшие в другом.
Однако, здесь есть некоторое ограничение. Из соображений безопасности, програмам разрешается доступ только к тем окнам, документы в которых либо созданы из программы, либо загружены с того же сервера с которого загружен и документ текущего окна. Мы еще столнемся с этим ограничением в теме DHTML. Там же мы посмотрим, как с ним бороться.
Мы не будем рассматривать здесь способы описания фреймов, атрибут TARGET и т.п. Все это должно быть Вам известно из курса HTML. Если кто-то забыл, посмотрите описание HTML. Мы же сосредоточимся на доступе к фреймам из программ на JavaScript.
Когда мы говорили об окнах, то мы отмечали, что они все равноправны. Елинственное, что связывало порожденное окно с породившим - свойство opener.
С фреймами дело обстоит иначе. Все фреймы созданные в окне, являются потомками этого окна. Если внутри фрейма загружен документ, который, в свою очередь, содержит FRAMESET то фреймы этого FRAMESET являются потомками родительского фрейма и т.д. В остальном же фреймы подобны окнам. Они обладают всеми свойствами объекта window.
Для организации связи родитель-потомок служат свойства объекта window: parent - окно-родитель (фрейм-родитель) и top - окно самого верхнего уровня.
Рассмотрим окно в котором определены следующие тэги.
<FRAMESET COLS="50%,*"> <FRAMESET ROWS="30%,*"> <FRAME NAME="fr1" SRC="javascript:void(0)"></FRAME> <FRAME NAME="fr2" SRC="javascript:void(0)"></FRAME> </FRAMESET> <FRAME NAME="fr3" SRC="javascript:void(0)"></FRAME> </FRAMESET>
В этом окне определены три фрейма. Все они являются потомками текущего окна. Значит, все они являются элементами массива frames текущего окна. Таким образом, мы можем обращаться к ним по их именам, через массив frames, а именно frames["fr1"], frames["fr2"] и frames["fr3"].
На самом деле, поскольку их имена уникальны, можно обращаться и просто по именам, минуя массив frames - fr1, fr2 и fr3.
Ну, а что делать, если программа определенная в документе, загруженном во фрейм fr1, захочет добраться до фрейма fr2? Да, именно так, как Вы подумали, она должна обратиться к fr2 через главное окно: top.fr2 или parent.fr2, поскольку в данном случае окно - родитель одновременно является и окном самого верхнего уровня.
Ниже приведен текст некой страницы. Посмотрите и попытайтесь понять что там к чему.
<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251"> <TITLE>Пример фреймов</TITLE> <SCRIPT LANGUAGE="JavaScript"> function writeToFrames() { fr1.document.write("<H1>Фрейм 1</H1>Попали?"); fr2.document.write("<H1>Фрейм 2</H1>Попали?"); fr3.document.write("<H1>Фрейм 3</H1>Попали?"); } onload = writeToFrames; </SCRIPT> </HEAD> <FRAMESET COLS="50%,*"> <FRAMESET ROWS="30%,*"> <FRAME NAME="fr1"></FRAME> <FRAME NAME="fr2"></FRAME> </FRAMESET> <FRAME NAME="fr3"></FRAME> </FRAMESET> </HTML>
Посмотрели? Теперь загрузите ее и проверьте соответствует ли действительность Вашим ожиданиям?
Теперь, когда мы знаем как именовать фреймы и как добираться из одного в другой, мы можем делать с фреймами абсолютно все, что мы делали с окнами - писать в них, загружать в них другие документы и т.д. и т.п.
Мне осталось лишь дать маленький совет и привести еще один полезный пример.
Старайтесь размещать Ваши JavaScript функции в самом главном документе, там где у Вас находится FRAMESET. Это даст Вам уверенность, что когда бы некая функция ни понадобилась документу расположенному во фрейме, она уже будет доступна, ведь главный документ грузится из сети первым.
И последний пример. Допустим, Вы разработали страницу, состоящую из нескольких фреймов и Вам бы очень не хотелось, чтобы документы, предназначенные для показа во фреймах, кто-то загружал бы как главные - прямо в окно. Например, они при этом непонятны или еще что-нибудь.
Как с этим бороться? Очевидно, документ, предназначенный для показа во фрейме, должен проверять, а не загрузили ли его как самостоятельный? И, если так, то немедленно загружать, вместо себя, свою главную - фреймосодержащую страницу.
Для решения этой задачи, достаточно, в самом начале документов, предназначенных для показа во фреймах, расположить такой простой код:
if (self==parent) location.replace("mainpage.html");
Здесь предполагается, что главная страница называется mainpage.html.
Есть еще один, более полный (вернее, более близкий к реальной жизни) пример. Посмотрите его и попробуйте написать самостоятельно. Если же совсем не получится, разберите хотя бы его исходный текст.
Главная страница | Замечания? Комментарии? Идеи? |